
#include "imtPublic.h"
#include "imtInputer.h"

namespace iMate {

	MouseButton convertOISMouseButtonToMine(const OIS::MouseState& ms)
	{
		if (ms.buttonDown(OIS::MB_Left)) return LeftButton;
		if (ms.buttonDown(OIS::MB_Right)) return RightButton;
		if (ms.buttonDown(OIS::MB_Middle)) return MiddleButton;
		if (ms.buttonDown(OIS::MB_Button3)) return X1Button;
		return NoButton;
	}

	/**a process for input event
	@timeDelta   time elapsed since previous frame
	*/
	void Inputer::update(Real timeDelta)
	{
	}
	
	void Inputer::shutdown()
	{
	}

	bool Inputer::mouseMoved( const MouseEvent &arg )
	{
		WipeEvent evt(arg.state.X.rel, arg.state.Y.rel, arg.state.Z.rel, convertOISMouseButtonToMine(arg.state), 0.5f);
		evt.setMousePosition(arg.state.X.abs, arg.state.Y.abs);
		return eWipeHandler.notify(this, evt);
	}
	bool Inputer::mousePressed( const MouseEvent &arg, MouseButtonID id )
	{
		if (OIS::MB_Left == id)
		{
			PressEvent evt(arg.state.X.abs, arg.state.Y.abs);
			mPrvPressPosX = evt.x;
			mPrvPressPosY = evt.y;
			mTouchTimer.reset();

			return ePressHandler.notify(this, evt);
		}
		return false;
	}
	bool Inputer::mouseReleased( const MouseEvent &arg, MouseButtonID id )
	{
		if (OIS::MB_Left == id)
		{
			ReleaseEvent evt(arg.state.X.abs, arg.state.Y.abs);
			bool b = eReleaseHandler.notify(this, evt);

			if (isTouch(evt.x, evt.y))
			{
				TouchEvent touchEvt(evt.x, evt.y);
				eTouchHandler.notify(this, touchEvt);
			}

			return b;
		}
		return false;
	}
	bool Inputer::keyPressed( const KeyEvent &arg )
	{
		mKeyStateAlive = true;
		KeyPressEvent evt(arg.key, arg.text);
		bool re = eKeyPressHandler.notify(this, evt);
		mKeyStateAlive = !evt.isConsumed();
		return re;
	}
	bool Inputer::keyReleased( const KeyEvent &arg )
	{
		KeyReleaseEvent evt(arg.key, arg.text);
		return eKeyReleaseHandler.notify(this, evt);
	}
	bool Inputer::isTouch(int curX, int curY)
	{
		const DWORD TOUCH_TIME_ELAPSED = 300;
		const int TOUCH_CHESS_OFFSET = 50;

		return (mTouchTimer.getMilliseconds() < TOUCH_TIME_ELAPSED)
			&& (TOUCH_CHESS_OFFSET > (::abs(mPrvPressPosX - curX) + ::abs(mPrvPressPosY - curY)));
	}

	bool Inputer::isKeyDown(const int key)
	{
		assert(mKeyboard);
		return mKeyStateAlive && mKeyboard->isKeyDown((OIS::KeyCode)key);
	}
	bool Inputer::isKeyUp(const int key)
	{
		return !isKeyDown(key);
	}

}//iMate
